From dfc4d9ab9e11c2d2527b821f34ed416c9d6f35d9 Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Thu, 12 Aug 2004 11:15:06 +0000 Subject: [PATCH] bitkeeper revision 1.1159.1.41 (411b513abSOkSWbJ0fLA8-ej90H_yA) Fixes in configuring a migrated domain. --- .rootkeys | 1 + tools/python/xen/xend/XendDomain.py | 8 +- tools/xfrd/http.h | 50 +++++++++ tools/xfrd/xen_domain.c | 157 +++++++++++++++++++++------- 4 files changed, 177 insertions(+), 39 deletions(-) create mode 100644 tools/xfrd/http.h diff --git a/.rootkeys b/.rootkeys index eca19dc2bc..4e5126a5a4 100644 --- a/.rootkeys +++ b/.rootkeys @@ -476,6 +476,7 @@ 40e9808eZpbdn9q2KSSMGCNvY_ZgpQ tools/xfrd/enum.h 40e9808easXCzzAZQodEfKAhgUXSPA tools/xfrd/hash_table.c 40e9808e94BNXIVVKBFHC3rnkvwtJg tools/xfrd/hash_table.h +411b5139tfKZfWs1LQHmwDR_wjKoxQ tools/xfrd/http.h 40e9808epW9iHcLXuO3QfUfLzB7onw tools/xfrd/lexis.c 40e9808egccMhCizayQRGtpBA3L5MQ tools/xfrd/lexis.h 40e9808ePADCSKL1YgGCt2TbYPnYkw tools/xfrd/lzi_stream.c diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 313abe6881..bffbdee46b 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -366,9 +366,11 @@ class XendDomain: @param config: configuration @return: deferred """ - dominfo = self.domain_get(id) - if not dominfo: - raise XendError("Invalid domain: " + str(id)) + print 'domain_configure>', id, config + dominfo = self.domain_lookup(id) + print 'domain_configure>', 'dominfo=', dominfo + for dinfo in self.domain_by_id.values(): + print 'domain', dinfo.id, dinfo.name log.debug('domain_configure> id=%s config=%s', id, str(config)) if dominfo.config: raise XendError("Domain already configured: " + dominfo.name) diff --git a/tools/xfrd/http.h b/tools/xfrd/http.h new file mode 100644 index 0000000000..711ccc9787 --- /dev/null +++ b/tools/xfrd/http.h @@ -0,0 +1,50 @@ +#ifndef _XFRD_HTTP_H_ +#define _XFRD_HTTP_H_ + +enum { + HTTP_OK = 200, + HTTP_CREATED = 201, + HTTP_ACCEPTED = 202, + HTTP_NON_AUTHORITATIVE_INFORMATION = 203, + HTTP_NO_CONTENT = 204, + HTTP_RESET_CONTENT = 205, + HTTP_PARTIAL_CONTENT = 206, + HTTP_MULTI_STATUS = 207, + + HTTP_MULTIPLE_CHOICE = 300, + HTTP_MOVED_PERMANENTLY = 301, + HTTP_FOUND = 302, + HTTP_SEE_OTHER = 303, + HTTP_NOT_MODIFIED = 304, + HTTP_USE_PROXY = 305, + HTTP_TEMPORARY_REDIRECT = 307, + + HTTP_BAD_REQUEST = 400, + HTTP_UNAUTHORIZED = 401, + HTTP_PAYMENT_REQUIRED = 402, + HTTP_FORBIDDEN = 403, + HTTP_NOT_FOUND = 404, + HTTP_NOT_ALLOWED = 405, + HTTP_NOT_ACCEPTABLE = 406, + HTTP_PROXY_AUTH_REQUIRED = 407, + HTTP_REQUEST_TIMEOUT = 408, + HTTP_CONFLICT = 409, + HTTP_GONE = 410, + HTTP_LENGTH_REQUIRED = 411, + HTTP_PRECONDITION_FAILED = 412, + HTTP_REQUEST_ENTITY_TOO_LARGE = 413, + HTTP_REQUEST_URI_TOO_LONG = 414, + HTTP_UNSUPPORTED_MEDIA_TYPE = 415, + HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416, + HTTP_EXPECTATION_FAILED = 417, + + HTTP_INTERNAL_SERVER_ERROR = 500, + HTTP_NOT_IMPLEMENTED = 501, + HTTP_BAD_GATEWAY = 502, + HTTP_SERVICE_UNAVAILABLE = 503, + HTTP_GATEWAY_TIMEOUT = 504, + HTTP_VERSION_NOT_SUPPORTED = 505, + HTTP_INSUFFICIENT_STORAGE_SPACE = 507, + HTTP_NOT_EXTENDED = 510, +}; +#endif /* ! _XFRD_HTTP_H_ */ diff --git a/tools/xfrd/xen_domain.c b/tools/xfrd/xen_domain.c index 27135b95ef..a5d18c0199 100644 --- a/tools/xfrd/xen_domain.c +++ b/tools/xfrd/xen_domain.c @@ -136,9 +136,16 @@ int xen_domain_rcv(IOStream *io, uint32_t *dom, char **vmconfig, int *vmconfig_n } #include +#include "http.h" +/** Flag indicating whether we need to initialize libcurl. + */ static int do_curl_global_init = 1; +/** Get a curl handle, initializing libcurl if needed. + * + * @return curl handle + */ static CURL *curlinit(void){ if(do_curl_global_init){ do_curl_global_init = 0; @@ -150,37 +157,136 @@ static CURL *curlinit(void){ return curl_easy_init(); } +/** Curl debug function. + */ int curldebug(CURL *curl, curl_infotype ty, char *buf, size_t buf_n, void *data){ printf("%*s\n", buf_n, buf); return 0; } -/** Configure a new domain. Talk to xend using libcurl. +/** Setup a curl handle with a url. + * Creates the url by formatting 'fmt' and the remaining arguments. + * + * @param pcurl return parameter for the curl handle + * @param url url buffer + * @param url_n size of url + * @param fmt url format string, followed by parameters + * @return 0 on success, error code otherwise */ -int xen_domain_configure(uint32_t dom, char *vmconfig, int vmconfig_n){ +static int curlsetup(CURL **pcurl, char *url, int url_n, char *fmt, ...){ int err = 0; + va_list args; CURL *curl = NULL; - CURLcode curlcode = 0; - char domainurl[128] = {}; - int domainurl_n = sizeof(domainurl) - 1; - int n; - struct curl_httppost *form = NULL, *last = NULL; - CURLFORMcode formcode = 0; + int n = 0; - dprintf("> dom=%u\n", dom); curl = curlinit(); if(!curl){ eprintf("> Could not init libcurl\n"); err = -ENOMEM; goto exit; } - n = snprintf(domainurl, domainurl_n, - "http://localhost:%d/xend/domain/%u", XEND_PORT, dom); - if(n <= 0 || n >= domainurl_n){ + url_n -= 1; + va_start(args, fmt); + n = vsnprintf(url, url_n, fmt, args); + va_end(args); + if(n <= 0 || n >= url_n){ err = -ENOMEM; - eprintf("Out of memory in url.\n"); + eprintf("> Out of memory in url\n"); + goto exit; + } + dprintf("> url=%s\n", url); +#if DEBUG + // Verbose. + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); + // Call the debug function on data received. + curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, curldebug); +#else + // No progress meter. + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); + // Completely quiet. + curl_easy_setopt(curl, CURLOPT_MUTE, 1); +#endif + // Set the URL. + curl_easy_setopt(curl, CURLOPT_URL, url); + exit: + if(err && curl){ + curl_easy_cleanup(curl); + curl = NULL; + } + *pcurl = curl; + return err; +} + +/** Make the http request stored in the curl handle and get + * the result code from the curl code and the http return code. + * + * @param curl curl handle + * @return 0 for success, error code otherwise + */ +int curlresult(CURL *curl){ + int err = 0; + CURLcode curlcode = 0; + long httpcode = 0; + + curlcode = curl_easy_perform(curl); + if(curlcode){ + eprintf("> curlcode=%d\n", curlcode); + err = -EINVAL; + goto exit; + } + curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &httpcode); + if(httpcode != HTTP_OK){ + eprintf("> httpcode=%d\n", (int)httpcode); + err = -EINVAL; goto exit; } + exit: + return err; +} + +/** Get xend to list domains. + * We use this to force xend to refresh its domain list. + * + * @return 0 on success, error code otherwise + */ +int xen_domain_ls(void){ + int err = 0; + CURL *curl = NULL; + char url[128] = {}; + int url_n = sizeof(url); + + dprintf(">\n"); + err = curlsetup(&curl, url, url_n, "http://localhost:%d/xend/domain", XEND_PORT); + if(err) goto exit; + err = curlresult(curl); + exit: + if(curl) curl_easy_cleanup(curl); + dprintf("< err=%d\n", err); + return err; +} + +/** Get xend to configure a new domain. + * + * @param dom domain id + * @param vmconfig configuration string + * @param vmconfig_n length of vmconfig + * @return 0 on success, error code otherwise + */ +int xen_domain_configure(uint32_t dom, char *vmconfig, int vmconfig_n){ + int err = 0; + CURL *curl = NULL; + char url[128] = {}; + int url_n = sizeof(url); + struct curl_httppost *form = NULL, *last = NULL; + CURLFORMcode formcode = 0; + + dprintf("> dom=%u\n", dom); + // List domains so that xend will update its domain list and notice the new domain. + xen_domain_ls(); + + err = curlsetup(&curl, url, url_n, "http://localhost:%d/xend/domain/%u", XEND_PORT, dom); + if(err) goto exit; + // Config field - set from vmconfig. formcode = curl_formadd(&form, &last, CURLFORM_COPYNAME, "config", @@ -201,36 +307,15 @@ int xen_domain_configure(uint32_t dom, char *vmconfig, int vmconfig_n){ if(formcode){ eprintf("> Error adding op field.\n"); + err = -EINVAL; goto exit; } - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); - curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, curldebug); - // No progress meter. - //curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); - // Completely quiet. - //curl_easy_setopt(curl, CURLOPT_MUTE, 1); - // Set the URL. - curl_easy_setopt(curl, CURLOPT_URL, domainurl); // POST the form. curl_easy_setopt(curl, CURLOPT_HTTPPOST, form); - dprintf("> curl perform...\n"); -#if 0 && defined(_XEN_XFR_STUB_) - dprintf("> _XEN_XFR_STUB_ defined - not calling xend\n"); - curlcode = 0; -#else - curlcode = curl_easy_perform(curl); -#endif + err = curlresult(curl); exit: if(curl) curl_easy_cleanup(curl); if(form) curl_formfree(form); - if(formcode){ - dprintf("> formcode=%d\n", formcode); - err = -EINVAL; - } - if(curlcode){ - dprintf("> curlcode=%d\n", curlcode); - err = -EINVAL; - } dprintf("< err=%d\n", err); return err; } -- 2.30.2